#pragma once
#include <iostream>
#include <pthread.h>
#include "myh/MyLog.hpp"
class PthMutex
{
public:
    PthMutex()
        : _lock(new pthread_mutex_t)
    {
        int ret = pthread_mutex_init(_lock, nullptr);
        HandleRet("pthread_mutex_init", ret);
    }
    void lock()
    {
        int ret = pthread_mutex_lock(_lock);
        HandleRet("pthread_mutex_lock", ret);
    }
    void unlock()
    {
        int ret = pthread_mutex_unlock(_lock);
        HandleRet("pthread_mutex_unlock", ret);
    }
    ~PthMutex()
    {
        int ret = pthread_mutex_destroy(_lock);
        HandleRet("pthread_mutex_destroy", ret);
        delete _lock;
    }
    pthread_mutex_t* getlock() {return _lock;}
private:
    void HandleRet(const std::string &funname, int _error)
    {
        if (_error)
        {
            lg.defaultprint("funname", _error);
        }
    }
    pthread_mutex_t *_lock;
};

class Guardlock
{
public:
    Guardlock()
        : _plock(new PthMutex)
    {
        _plock->lock();
    }
    ~Guardlock()
    {
        _plock->unlock();
        delete _plock;
    }

private:
    PthMutex *_plock;
};

class PthCond
{
public:
    PthCond()
        : _cond(new pthread_cond_t)
    {
        int ret = pthread_cond_init(_cond,nullptr);
        HandleRet("pthread_cond_init", ret);
    }
    ~PthCond()
    {
        int ret = pthread_cond_destroy(_cond);
        HandleRet("pthread_cond_destroy", ret);
        delete _cond;
    }
    void wait(pthread_mutex_t * lock)
    {
        int ret = pthread_cond_wait(_cond, lock);
        HandleRet("pthread_cond_wait", ret);
    }
    void signal()
    {
        int ret = pthread_cond_signal(_cond);
        HandleRet("pthread_cond_signal", ret);
    }
private:
    void HandleRet(const std::string &funname, int _error)
    {
        if (_error)
        {
            lg.defaultprint("funname", _error);
        }
    }
    pthread_cond_t *_cond;
};
